# coding:UTF-8
# 导入需要的库
import sys, pygame, random
from pygame.locals import *

# 基础初始化操作
# Pygame游戏库初始化
pygame.init()
# 创建时钟对象 (可以控制游戏循环频率)
clock = pygame.time.Clock()
# 控制重复响应持续按下按键的时间，10毫秒以上
pygame.key.set_repeat(10)
# 设置窗口标题
pygame.display.set_caption("贪吃蛇")
windowWidth = 600
windowHeight = 600
cellSize = 20
# 创建显示窗口
screen = pygame.display.set_mode((windowWidth, windowHeight))
screen.fill([129, 216, 208])  
# 资源导入
#颜色色号：覆盆子红RGB 158/46/36虎皮黄 RGB 226/175/66薄荷绿 RGB 64/125/82草黄 RGB 207/182/74星蓝 RGB： 154/180/205鸢尾蓝 RGB： 65/138/180苋菜紫 RGB： 142/41/97钢蓝 RGB： 16/20/32云峰白 RGB： 218/227/230岩石棕RGB： 140/80/44橄榄石绿 RGB： 184/206/142竹绿 RGB: 79/164/133钴蓝 RGB:  70/146/185月影白 RGB：194/196/195笋皮棕 RGB：107/51/26

# 定义各种类
# 定义贪吃蛇类
class Snack():
    def __init__(self):
        self.body = []  # 记录全部顶点
        self.newHead_x = 0
        self.newHead_y = 0
        self.move_direction = 3  # 0123，分别代表上左右下
        self.turn_direction = 3  # 0123，分别代表上左右下
        self.color = Color(218, 227, 230)
    # 在屏幕上画出自己
    def draw(self):
        # pygame.draw.rect(surface,color,Rect,width=0) 画一个矩形
        for point in self.body:
            pygame.draw.rect(screen, self.color,
                             (point[0], point[1], cellSize, cellSize))
    # 随机出生
    def born(self):
        self.body = []
        x = cellSize*random.randint(8, windowWidth/cellSize-8)
        y = cellSize*random.randint(8, windowHeight/cellSize-8)
        for i in range(3):
            self.body.append([x, y - i*cellSize])
    # 根据方向计算新头坐标
    def newHead(self, direction):
        if direction == 0:  # 向上
            self.newHead_x = self.body[0][0]
            self.newHead_y = self.body[0][1] - cellSize
            if self.body[0][1] == 0:  # 穿墙
                self.newHead_y = cellSize*(windowHeight/cellSize - 1)
        elif direction == 1:  # 向左
            self.newHead_x = self.body[0][0] - cellSize
            self.newHead_y = self.body[0][1]
            if self.body[0][0] == 0:
                self.newHead_x = cellSize*(windowHeight/cellSize - 1)
        elif direction == 2:  # 向右
            self.newHead_x = self.body[0][0] + cellSize
            self.newHead_y = self.body[0][1]
            if self.body[0][0] == cellSize*(windowHeight/cellSize - 1):
                self.newHead_x = 0
        elif direction == 3:  # 向下
            self.newHead_x = self.body[0][0]
            self.newHead_y = self.body[0][1] + cellSize
            if self.body[0][1] == cellSize*(windowHeight/cellSize - 1):
                self.newHead_y = 0

    # 默认坚持之前移动方向，最后一块消失，新增第一块
    def move(self):
        self.newHead(self.move_direction)
        if self.eatObject(AllVar.apple):  #如果吃到苹果，则增加头部，不删除尾巴即可
            self.body.insert(0, [self.newHead_x, self.newHead_y])
            AllVar.apple.born()
            return
        if self.eatObject(AllVar.long):  #如果吃到变长道具，则身子扩展成2倍长度
            self.body.insert(0, [self.newHead_x, self.newHead_y])
            self.body.pop(-1)
            long = len(self.body)
            for i in range(long):
                self.body.append([self.body[long-1][0],self.body[long-1][1]- i*cellSize])
            AllVar.long.born()
            return
        if self.eatObject(AllVar.appleBig):  #如果吃到苹果变大道具，则苹果大成2倍
            AllVar.apple.body.append\
            ([AllVar.apple.body[0][0]+cellSize, AllVar.apple.body[0][1]])
            AllVar.apple.body.append\
            ([AllVar.apple.body[0][0], AllVar.apple.body[0][1]+cellSize])
            AllVar.apple.body.append\
            ([AllVar.apple.body[0][0]+cellSize, AllVar.apple.body[0][1]+cellSize])
            AllVar.appleBig.born()
            return
        self.body.pop(-1)
        self.body.insert(0, [self.newHead_x, self.newHead_y])
        print(self.body)
    # 转向，修改生成新头的方向
    def turn(self, direction):
        if self.move_direction + direction != 3:
            self.move_direction = direction
    # 吃到道具
    def eatObject(self, object):
        for point in object.body:
            if self.newHead_x == point[0] and self.newHead_y == point[1]:
                return True
        return False

# 普通苹果
class Apple():
    def __init__(self):
        self.body = []  # 记录全部顶点
        self.color = Color(158, 46, 36)
    # 绘制
    def draw(self):
        for point in self.body:
            pygame.draw.rect(screen, self.color,(point[0], point[1], cellSize, cellSize))
    # 随机产生
    def born(self):
        self.body = []
        x = cellSize*random.randint(8, windowWidth/cellSize-8)
        y = cellSize*random.randint(8, windowHeight/cellSize-8)
        self.body.append([x, y])
        
# 苹果变大道具
class AppleBig():
    def __init__(self):
        self.body = []  # 记录全部顶点
        self.color = Color(65, 138, 180) 
    # 绘制
    def draw(self):
        for point in self.body:
            pygame.draw.rect(screen, self.color,
                             (point[0], point[1], cellSize, cellSize))
    # 随机产生
    def born(self):
        self.body = []
        x = cellSize*random.randint(8, windowWidth/cellSize-8)
        y = cellSize*random.randint(8, windowHeight/cellSize-8)
        self.body.append([x, y ])

# 变长道具
class Long():
    def __init__(self):
        self.body = []  # 记录全部顶点
        self.color = Color(0, 0, 0)
    # 绘制
    def draw(self):
        for point in self.body:
            pygame.draw.rect(screen, self.color,
                             (point[0], point[1], cellSize, cellSize))
    # 随机产生
    def born(self):
        self.body = []
        x = cellSize*random.randint(8, windowWidth/cellSize-8)
        y = cellSize*random.randint(8, windowHeight/cellSize-8)
        self.body.append([x, y ])

# 各种工具方法
# 绘制网格
def drawGrid():
    for i in range(cellSize, windowWidth, cellSize):
        pygame.draw.line(screen, (255, 255, 255), (i, 0), (i, windowHeight), 1)
    for j in range(cellSize, windowHeight, cellSize):
        pygame.draw.line(screen, (255, 255, 255), (0, j), (windowWidth, j), 1)


# 创建全局变量类
class AllVar():
    snake = None
    apple = None
    long   = None
    appleBig=None
    state = ''


# 创建全部变量
AllVar.snake = Snack()
AllVar.apple = Apple()
AllVar.long   = Long()
AllVar.appleBig = AppleBig()
AllVar.state = 'start'

# 初始化游戏
def initGame():
    AllVar.snake.born()
    AllVar.apple.born()
    AllVar.long.born()
    AllVar.appleBig.born()


# 开始界面显示文字
def drawText():
    fontObj1 = pygame.font.Font('freesansbold.ttf', 60)
    textSurfaceObj1 = fontObj1.render('Snack', True, (218, 227, 230))
    textRectObj1 = textSurfaceObj1.get_rect()
    textRectObj1.center = (windowWidth/2, windowHeight/3)
    screen.blit(textSurfaceObj1, textRectObj1)
    fontObj2 = pygame.font.Font('freesansbold.ttf', 30)
    textSurfaceObj2 = fontObj2.render(
        'developer: fcou ', True, (218, 227, 230))
    textRectObj2 = textSurfaceObj2.get_rect()
    textRectObj2.center = (windowWidth/2, windowHeight*2/3)
    screen.blit(textSurfaceObj2, textRectObj2)

# 绘制全部对象
def paintAll():
    screen.fill([129, 216, 208])
    drawGrid()
    AllVar.snake.draw()
    AllVar.apple.draw()
    AllVar.long.draw()
    AllVar.appleBig.draw()

# 移动全部对象
def moveAll():
    AllVar.snake.move()


# 游戏流程控制
def controlState():
    if AllVar.state == 'start':
        screen.fill([129, 216, 208])
        drawText()
        handleEvent()
    elif AllVar.state == 'running':
        paintAll()
        moveAll()
        handleEvent()

# 控制贪吃蛇，处理交互逻辑
def handleEvent():
    for event in pygame.event.get():
        # 监听退出操作
        if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
            pygame.quit()
            sys.exit(-1)
        # 键盘控制贪吃蛇移动
        if event.type == KEYDOWN:
            if AllVar.state == 'start':
                AllVar.state = 'running'
                initGame()  # 游戏初始化
            if event.key == K_UP:
                AllVar.snake.turn(0)
            elif event.key == K_DOWN:
                AllVar.snake.turn(3)
            elif event.key == K_LEFT:
                AllVar.snake.turn(1)
            elif event.key == K_RIGHT:
                AllVar.snake.turn(2)


# 游戏循环 -> 意味着游戏的正式开始！
while True:
    # 通过时钟对象指定循环频率，每秒循环X次
    clock.tick(10)
    controlState()
    pygame.display.update()